package com.atguigu.gmall.cart.controller;

import org.junit.Test;

import java.util.HashMap;
import java.util.Optional;

/*
四、Java8新增了一个工具类/容器：java.util.Optional<T>
1、Optional类的对象是一个容器，容器就是用来装对象的
可能里面是空的，可能里面有一个对象，
这个类通常用来当做一个方法的返回值来使用，避免返回null值。

到目前为止，臭名昭著的空指针异常是导致Java应用程序失败的最常见原因。
以前，为了解决空指针异常，Google公司著名的Guava项目引入了Optional类，
Guava通过使用检查空值的方式来防止代码污染，它鼓励程序员写更干净的代码。
受到Google Guava的启发，Optional类已经成为Java 8类库的一部分。

例如：Stream的API中的一些方法返回值就是Optional类。
| **Optional<T>** **findFirst()**            | 返回第一个元素                                               |
| **Optional<T>** **findAny()**              | 返回当前流中的任意元素                                       |                                       |
| **Optional<T>** **max(Comparator c)**      | 返回流中最大值                                               |
| **Optional<T>** **min(Comparator c)**     |返回流中的最小值
因为流中可能没有元素，那么这些方法就没有真正的元素返回，如果没有Optional，就需要返回null，
调用这些方法的地方，就可能发生空指针异常。

2、如何创建一个Optional类的对象
（1）创建一个空的容器对象       Optional.empty();
（2）创建一个容器对象，里面可能包含空值，可能包含具体值  Optional.ofNullable(x);  x可能为空
（3）创建一个非空的容器对象，  Optional.of(x);  x一定是非空

3、如花使用Optional
（1）判断是否为空
boolean isPresent()

（2）获取里面的对象
T get()  ：取出Optional容器中的对象，要求里面必须有对象，否则抛出 NoSuchElementException
T orElse(T other)  ：如果Optional容器中有对象，那么直接返回里面 的对象，否则返回备胎
T orElseGet(Supplier<? extends T> other)  ：如果Optional容器中有对象，那么直接返回里面 的对象，否则返回Supplier供给型接口提供的备胎

（3）void ifPresent(Consumer<? super T> consumer)
 */
public class test2 {
    @Test
    public void test01(){
        Optional<Object> empty = Optional.empty();
        System.out.println(empty);
    }

    @Test
    public void test03(){
        Optional<String> opt = findGirlFriend2("汪飞");
        System.out.println("opt1 = " + opt);
        System.out.println("汪飞的女朋有是否存在： " + opt.isPresent());
        System.out.println("女朋友：" + opt.orElse("石榴姐"));
        System.out.println("女朋友：" + opt.get());
        opt.ifPresent(System.out::println);//如果女朋友存在，就打印，否则就不打印

        Optional<String> opt2 = findGirlFriend2("李天棋");
        System.out.println("opt2 = " + opt2);// Optional.empty
        System.out.println("李天棋的女朋有是否存在： " + opt2.isPresent());
        System.out.println("女朋友：" + opt2.orElse("石榴姐"));
        System.out.println("女朋友：" + opt2.orElseGet(String::new));//空字符串
        opt2.ifPresent(System.out::println);//如果女朋友存在，就打印，否则就不打印

    }

    public Optional<String> findGirlFriend2(String boyName){
        HashMap<String,String > map = new HashMap<>();//这个集合后面是数据库中的数据
        map.put("汪飞", "如花");
        map.put("二虎", "翠花");
        map.put("邱世玉", "似玉");
        map.put("李天棋", null);

        return Optional.ofNullable(map.get(boyName));
    }

    @Test
    public void test02(){
        String girl1 = findGirlFriend("汪飞");
        System.out.println("girl1 = " + girl1);
        System.out.println("姓：" + girl1.charAt(0));

        String girl2 = findGirlFriend("二虎");
        System.out.println("girl2 = " + girl2);
        System.out.println("姓：" + girl2.charAt(0));
    }
    public String findGirlFriend(String boyName){
        HashMap<String,String > map = new HashMap<>();//这个集合后面是数据库中的数据
        map.put("汪飞", "如花");
        map.put("二虎", "翠二花");
        map.put("邱世玉", "似玉");
        map.put("李天棋", null);

        return map.get(boyName);

    }
}
